// Get the "extensions.vilplus." branch
const VIL_prefsService = Components.classes["@mozilla.org/preferences-service;1"]
		.getService(Components.interfaces.nsIPrefService);
const VIL_consoleService = Components.classes["@mozilla.org/consoleservice;1"]
		.getService(Components.interfaces.nsIConsoleService);
const VIL_dirService = Components.classes["@mozilla.org/file/directory_service;1"]
		.getService(Components.interfaces.nsIProperties);
const VIL_ioService = Components.classes["@mozilla.org/network/io-service;1"]
		.getService(Components.interfaces.nsIIOService);
const VIL_nsIScriptError = Components.interfaces.nsIScriptError;
var vilPlusPrefs = VIL_prefsService.getBranch("extensions.vilplus.");
var _gel = function(id, node) {
	if ("undefined" == typeof node || !node || !node.getElementById) {
		node = document;
	}
	return node.getElementById(id);
}
var Logger = function(loggername, level) {
	const LEVEL_ALL = -999;
	const LEVEL_DEBUG = 0;
	const LEVEL_INFO = 1;
	const LEVEL_WARN = 2;
	const LEVEL_ERROR = 3;
	const LEVEL_FATAL = 4;
	const LEVEL_NONE = 999;
	var myname = loggername ? loggername : "DefaultLogger";
	if (level) {
		this.logLevel = level;
	} else {
		try {
			this.logLevel = vilPlusPrefs.getIntPref("loglevel." + loggername);
		} catch (err) {
			// ignore pref not found
			this.logLevel = vilPlusPrefs.getIntPref("loglevel");
		}
	}
	this.debug = function(aMessage) {
		if (this.logLevel > LEVEL_DEBUG)
			return;
		VIL_consoleService.logStringMessage(myname + " [DEBUG]:" + aMessage);
	};
	this.info = function(aMessage) {
		if (this.logLevel > LEVEL_INFO)
			return;
		VIL_consoleService.logStringMessage(myname + " [INFO]:" + aMessage);
	};
	this.warn = function(aMessage, err) {
		if (this.logLevel > LEVEL_WARN)
			return;
		var msg = myname + " [WARN]:" + aMessage;
		logMessage(msg, err, VIL_nsIScriptError.warningFlag);
	};
	this.error = function(aMessage, err) {
		if (this.logLevel > LEVEL_ERROR)
			return;
		var msg = myname + " [ERROR]:" + aMessage;
		logMessage(msg, err, VIL_nsIScriptError.errorFlag);
	};
	this.fatal = function(aMessage, err) {
		if (this.logLevel > LEVEL_FATAL)
			return;
		var msg = myname + " [FATAL]:" + aMessage;
		logMessage(msg, err, VIL_nsIScriptError.exceptionFlag);
	};
	function logMessage(aMessage, err, flag) {
		if (err) {
			var scriptError = Components.classes['@mozilla.org/scripterror;1']
					.createInstance(Components.interfaces.nsIScriptError);
			scriptError.init(msg + ", reason: " + err.message, err.sourceName,
					err.sourceLine, err.lineNumber, err.columnNumber, flag,
					null);
			VIL_consoleService.logMessage(scriptError);
		} else {
			VIL_consoleService.logStringMessage(msg);
		}
	}
}

var defaultLogger = new Logger("DefaultLogger");

function isDef(ref) {
	return 'undefined' != typeof ref;
}

function getScriptFile(fileName) {
	var conf = getConfigDir();
	conf.append(fileName);
	return conf;
}

function getConfigDir() {
	var profdir = VIL_dirService.get("ProfD",
			Components.interfaces.nsILocalFile);
	var confdir = profdir.clone();
	confdir.append("vilplus_config");
	if (!confdir.exists()) {
		initVILPlusConfig(confdir);
	}
	return confdir;
}
function getContentDir() {
	var reg = Components.classes["@mozilla.org/chrome/chrome-registry;1"]
			.getService(Components.interfaces.nsIChromeRegistry);

	var proto = Components.classes["@mozilla.org/network/protocol;1?name=file"]
			.getService(Components.interfaces.nsIFileProtocolHandler);

	var chromeURL = VIL_ioService
			.newURI("chrome://vilplus/content", null, null);
	var fileURL = reg.convertChromeURL(chromeURL);
	var file = proto.getFileFromURLSpec(fileURL.spec).parent;

	return file
}
function initVILPlusConfig(configDir) {
	configDir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0700);

	var defaultConfigFile = getContentDir().parent;
	defaultConfigFile.append("defaults");
	defaultConfigFile.append("preferences");
	defaultConfigFile.append("default-config.xml");

	defaultConfigFile.copyTo(configDir, "config.xml");
	defaultConfigFile.permissions = 0644;

	return configDir;
}

function getContents(aURL, charset) {
	if (!charset) {
		charset = "UTF-8"
	}
	var scriptableStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
			.getService(Components.interfaces.nsIScriptableInputStream);
	// http://lxr.mozilla.org/mozilla/source/intl/uconv/idl/nsIScriptableUConv.idl
	var unicodeConverter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
			.createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
	unicodeConverter.charset = charset;

	var channel = VIL_ioService.newChannelFromURI(aURL);
	var input = channel.open();
	scriptableStream.init(input);
	var str = scriptableStream.read(input.available());
	scriptableStream.close();
	input.close();

	try {
		return unicodeConverter.ConvertToUnicode(str);
	} catch (e) {
		return str;
	}
}

function getWriteStream(file) {
	var stream = Components.classes["@mozilla.org/network/file-output-stream;1"]
			.createInstance(Components.interfaces.nsIFileOutputStream);

	stream.init(file, 0x02 | 0x08 | 0x20, 420, -1);

	return stream;
}

function getScriptFileURI(fileName) {
	return VIL_ioService.newFileURI(getScriptFile(fileName));
}
